local s, id = GetID()
function s.initial_effect(c)
    c:EnableReviveLimit()
    
    -- special summon
    local e1 = Effect.CreateEffect(c)
    e1:SetType(EFFECT_TYPE_FIELD)
    e1:SetCode(EFFECT_SPSUMMON_PROC)
    e1:SetProperty(EFFECT_FLAG_UNCOPYABLE)
    e1:SetRange(LOCATION_HAND)
    e1:SetCondition(s.spcon)
    e1:SetOperation(s.spop)
    c:RegisterEffect(e1)

    -- selfdes
    local e2 = Effect.CreateEffect(c)
    e2:SetType(EFFECT_TYPE_SINGLE)
    e2:SetProperty(EFFECT_FLAG_SINGLE_RANGE)
    e2:SetRange(LOCATION_MZONE)
    e2:SetCode(EFFECT_SELF_DESTROY)
    e2:SetCondition(s.descon)
    c:RegisterEffect(e2)

    -- spson
    local e11 = Effect.CreateEffect(c)
    e11:SetType(EFFECT_TYPE_SINGLE)
    e11:SetProperty(EFFECT_FLAG_CANNOT_DISABLE + EFFECT_FLAG_UNCOPYABLE)
    e11:SetCode(EFFECT_SPSUMMON_CONDITION)
    e11:SetValue(aux.FALSE)
    c:RegisterEffect(e11)

    local e0=Effect.CreateEffect(c)
	e0:SetType(EFFECT_TYPE_SINGLE)
	e0:SetProperty(EFFECT_FLAG_UNCOPYABLE)
	e0:SetCode(id)
	c:RegisterEffect(e0)
    local e4=Effect.CreateEffect(c)
	e4:SetType(EFFECT_TYPE_SINGLE)
	e4:SetProperty(EFFECT_FLAG_SINGLE_RANGE+EFFECT_FLAG_UNCOPYABLE)
	e4:SetRange(LOCATION_MZONE)
	e4:SetCode(EFFECT_SET_BASE_ATTACK)
	e4:SetCondition(function(e) return e:GetHandler():IsHasEffect(id) end)
	e4:SetValue(s.adval)
	c:RegisterEffect(e4)
	local e3=e4:Clone()
	e3:SetCode(EFFECT_SET_BASE_DEFENSE)
	c:RegisterEffect(e3)

    local e5 = Effect.CreateEffect(c)
    e5:SetDescription(aux.Stringid(800, 2))
    e5:SetCategory(CATEGORY_DESTROY)
    e5:SetType(EFFECT_TYPE_SINGLE + EFFECT_TYPE_TRIGGER_F)
    e5:SetCode(EVENT_TO_GRAVE)
    e5:SetCondition(s.erascon)
    e5:SetTarget(s.erastg)
    e5:SetOperation(s.erasop)
    c:RegisterEffect(e5)
end
s.listed_names = {27564031,57793869}

function s.spfilter(c)
    return c:IsCode(57793869) and c:IsAbleToGraveAsCost()
end
function s.spcon(e, c)
    if c == nil then
        return true
    end
    return Duel.GetLocationCount(c:GetControler(), LOCATION_MZONE) > 0 and
               Duel.IsExistingMatchingCard(s.spfilter, c:GetControler(), LOCATION_HAND + LOCATION_DECK, 0, 1, nil) and
               Duel.IsExistingMatchingCard(Card.IsSetCard, c:GetControler(), LOCATION_GRAVE, 0, 3, nil, 0x23)
end
function s.spop(e, tp, eg, ep, ev, re, r, rp, c)
    Duel.Hint(HINT_SELECTMSG, tp, HINTMSG_TOGRAVE)
    local tg = Duel.SelectMatchingCard(tp, s.spfilter, tp, LOCATION_HAND + LOCATION_DECK, 0, 1, 1, nil)
    if #tg<1 then return end
    Duel.SendtoGrave(tg, REASON_COST)
    Duel.BreakEffect()
end

function s.descon(e)
	return not (Duel.IsExistingMatchingCard(aux.FaceupFilter(Card.IsCode,27564031),e:GetHandlerPlayer(),LOCATION_ONFIELD,LOCATION_ONFIELD,1,nil) or Duel.IsEnvironment(27564031))
end

function s.adval(e, c)
    return Duel.GetFieldGroupCount(e:GetHandler():GetControler(), 0, LOCATION_ONFIELD) * 1000
end

function s.erascon(e)
    return e:GetHandler():IsReason(REASON_DESTROY)
end
function s.filter(c)
    return not c:IsRace(RACE_CREATORGOD) and c:IsFaceup()
end
function s.erastg(e, tp, eg, ep, ev, re, r, rp, chk)
    if chk == 0 then
        return true
    end
    local dg = Duel.GetMatchingGroup(nil, tp, LOCATION_ONFIELD, LOCATION_ONFIELD, nil)
    Duel.SetOperationInfo(0, CATEGORY_DESTROY, dg, dg:GetCount(), 0, 0)
end
function s.erasop(e, tp, eg, ep, ev, re, r, rp)
    local dg = Duel.GetMatchingGroup(nil, tp, LOCATION_ONFIELD, LOCATION_ONFIELD, nil)
    Duel.Destroy(dg, REASON_EFFECT)
end

function s.efilterr(e, te)
    local c = e:GetHandler()
    local tc = te:GetOwner()
    if tc == e:GetOwner() or te:IsHasProperty(EFFECT_FLAG_IGNORE_IMMUNE) then
        return false
    else
        return te:IsActiveType(TYPE_TRAP)
        --   or ((te:IsActiveType(TYPE_MONSTER) or te:IsActiveType(TYPE_SPELL)) and tc~=e:GetOwner())
        --    and ((te:GetType()==EFFECT_TYPE_FIELD and not (tc:GetTurnID()>=Duel.GetTurnCount() or (tc:GetFlagEffect(818)~=0 and tc:GetFlagEffectLabel(818)==c:GetFieldID())) )
        -- 	 or te:GetType()==EFFECT_TYPE_EQUIP and Duel.GetTurnCount()-tc:GetTurnID()>=1))
    end
end
function s.sdcon2(e, tp, eg, ep, ev, re, r, rp)
    local c = e:GetHandler()
    local tc = re:GetHandler()
    local eff=0
    for i = 1, 522 do
        if c:IsHasEffect(i) then
            local ae = {c:IsHasEffect(i)}
            for _, te in ipairs(ae) do
                if tc~=c and te:GetOwner()==tc and (te:GetType()==EFFECT_TYPE_SINGLE or te:GetType()==EFFECT_TYPE_EQUIP) and te:GetHandler()==c and not te:IsHasProperty(EFFECT_FLAG_IGNORE_IMMUNE) and not te:GetOwner():IsHasEffect(EFFECT_ULTIMATE_IMMUNE)
                and (te:IsActiveType(TYPE_SPELL) or te:IsActiveType(TYPE_MONSTER)) then 
                    eff=1
                    break 
                end
            end
        end
    end
    return eff==1
end
function s.sdop2(e, tp, eg, ep, ev, re, r, rp)
    local c = e:GetHandler()
    local tc = re:GetHandler()
    local eff=0
    for i = 1, 522 do
        if c:IsHasEffect(i) then
            local ae = {c:IsHasEffect(i)}
            for _, te in ipairs(ae) do
                if tc~=c and te:GetOwner()==tc and (te:GetType()==EFFECT_TYPE_SINGLE or te:GetType()==EFFECT_TYPE_EQUIP) and te:GetHandler()==c and not te:IsHasProperty(EFFECT_FLAG_IGNORE_IMMUNE) and not te:GetOwner():IsHasEffect(EFFECT_ULTIMATE_IMMUNE)
                and (te:IsActiveType(TYPE_SPELL) or te:IsActiveType(TYPE_MONSTER)) then 
                    eff=te
                    break 
                end
            end
        end
    end
    if eff==0 then return end
    local e83 = Effect.CreateEffect(c)
    e83:SetType(EFFECT_TYPE_FIELD + EFFECT_TYPE_CONTINUOUS)
    e83:SetRange(LOCATION_MZONE)
    e83:SetProperty(EFFECT_FLAG_IGNORE_IMMUNE + EFFECT_FLAG_CANNOT_DISABLE)
    e83:SetCountLimit(1)
    e83:SetCode(EVENT_PHASE + PHASE_END)
    e83:SetLabelObject(eff)
    e83:SetOperation(s.setop2)
    e83:SetReset(RESET_PHASE + PHASE_END)
    c:RegisterEffect(e83) 
end
function s.setop2(e, tp, eg, ep, ev, re, r, rp)
    local c = e:GetHandler()
    local te = e:GetLabelObject()
    if not te or te==0 then return end
    te:Reset()
end

function s.reop2(e, tp, eg, ep, ev, re, r, rp)
    local c = e:GetHandler()
    for i = 1, 430 do
        if c:IsHasEffect(i) then
            local ae = {c:IsHasEffect(i)}
            for _, te in ipairs(ae) do
                if te:GetOwner() ~= e:GetOwner() 
                and (te:IsActiveType(TYPE_SPELL) or te:IsActiveType(TYPE_MONSTER)) then
                    if te:GetType() == EFFECT_TYPE_FIELD then
                        local e80 = Effect.CreateEffect(c)
                        e80:SetType(EFFECT_TYPE_SINGLE)
                        e80:SetProperty(EFFECT_FLAG_SINGLE_RANGE + EFFECT_FLAG_CANNOT_DISABLE)
                        e80:SetRange(LOCATION_MZONE)
                        e80:SetCode(EFFECT_IMMUNE_EFFECT)
                        e80:SetValue(function(e, te2)
                            return te2 == te
                        end)
                        e80:SetReset(RESET_EVENT + 0x1fe0000)
                        c:RegisterEffect(e80)
                    elseif (te:GetType()==EFFECT_TYPE_SINGLE or te:GetType()==EFFECT_TYPE_EQUIP or te:GetType()==EFFECT_TYPE_GRANT or te:GetType()==EFFECT_TYPE_XMATERIAL)
					and not te:IsHasProperty(EFFECT_FLAG_IGNORE_IMMUNE) 
                    and not te:GetOwner():IsHasEffect(EFFECT_ULTIMATE_IMMUNE) then
                        te:Reset()
                    end
                end
            end
        end
    end
    for i = 2000, 2030 do
        if c:IsHasEffect(i) then
            local ae = {c:IsHasEffect(i)}
            for _, te in ipairs(ae) do
                if te:GetOwner() ~= e:GetOwner() 
                and (te:IsActiveType(TYPE_SPELL) or te:IsActiveType(TYPE_MONSTER)) then
                    if te:GetType() == EFFECT_TYPE_FIELD then
                        local e80 = Effect.CreateEffect(c)
                        e80:SetType(EFFECT_TYPE_SINGLE)
                        e80:SetProperty(EFFECT_FLAG_SINGLE_RANGE + EFFECT_FLAG_CANNOT_DISABLE)
                        e80:SetRange(LOCATION_MZONE)
                        e80:SetCode(EFFECT_IMMUNE_EFFECT)
                        e80:SetValue(function(e, te2)
                            return te2 == te
                        end)
                        e80:SetReset(RESET_EVENT + 0x1fe0000)
                        c:RegisterEffect(e80)
                    elseif (te:GetType()==EFFECT_TYPE_SINGLE or te:GetType()==EFFECT_TYPE_EQUIP or te:GetType()==EFFECT_TYPE_GRANT or te:GetType()==EFFECT_TYPE_XMATERIAL)
					and not te:IsHasProperty(EFFECT_FLAG_IGNORE_IMMUNE) 
                    and not te:GetOwner():IsHasEffect(EFFECT_ULTIMATE_IMMUNE) then
                        te:Reset()
                    end
                end
            end
        end
    end
end

function s.atcon(e)
    return bit.band(e:GetHandler():GetSummonType(), SUMMON_TYPE_SPECIAL) == SUMMON_TYPE_SPECIAL
end
function s.atlimit(e, c)
    return c ~= e:GetHandler()
end

function s.tgvalue(e, re, rp)
    return rp ~= e:GetHandlerPlayer() and re:GetHandler():GetTurnID() ~= Duel.GetTurnCount()
end

function s.lffilter(e, re, rp)
    return re:GetOwner() ~= e:GetHandler()
end